/**
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.sourceforge.stripes.authentication;

import org.apache.commons.codec.binary.Hex;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

class DigestCredentials
{
    String method = null;
    String username = null;
    String realm = null;
    String nonce = null;
    String nc = null;
    String cnonce = null;
    String qop = null;
    String uri = null;
    String response = null;

    DigestCredentials(String method)
    {
        this.method = method;
    }

    public boolean check(String password) throws UnsupportedEncodingException, NoSuchAlgorithmException
    {
        MessageDigest md = MessageDigest.getInstance("MD5");

        // Calculate the HA1 digest - username:realm:password

        md.update(username.getBytes("ISO-8859-1"));
        md.update((byte) ':');
        md.update(realm.getBytes("ISO-8859-1"));
        md.update((byte) ':');
        md.update(password.getBytes("ISO-8859-1"));
        byte[] ha1 = md.digest();
        String hexHa1 = new String(Hex.encodeHex(ha1));

        // Calculate the HA2 digest - method:uri

        md.reset();
        md.update(method.getBytes("ISO-8859-1"));
        md.update((byte) ':');
        md.update(uri.getBytes("ISO-8859-1"));
        byte[] ha2 = md.digest();
        String hexHa2 = new String(Hex.encodeHex(ha2));

        // Calculate the Response digest - ha1:nonce:nc:cnonce:qop:ha2

        md.reset();
        md.update(hexHa1.getBytes("ISO-8859-1"));
        md.update((byte) ':');
        md.update(nonce.getBytes("ISO-8859-1"));
        md.update((byte) ':');
        md.update(nc.getBytes("ISO-8859-1"));
        md.update((byte) ':');
        md.update(cnonce.getBytes("ISO-8859-1"));
        md.update((byte) ':');
        md.update(qop.getBytes("ISO-8859-1"));
        md.update((byte) ':');
        md.update(hexHa2.getBytes("ISO-8859-1"));

        byte[] digest = md.digest();
        String hexDigest = new String(Hex.encodeHex(digest));

        // check digest
        return (hexDigest.equalsIgnoreCase(response));
    }
}
